home *** CD-ROM | disk | FTP | other *** search
/ PC Elektro 3 / PC-Elektro-3-cd1.bin / KBan 2.0 / KBANSRC.LZH / SRC / PROG / BMPOUT.CPP next >
Encoding:
C/C++ Source or Header  |  1997-04-04  |  5.9 KB  |  209 lines

  1. #include "stdafx.h"
  2.  
  3. #include "bmpout.h"
  4.  
  5. // Convert the color format to a count of bits.
  6. static WORD get_color_bits(const BITMAP& bmp)
  7. {
  8.   WORD color_bits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel);
  9.  
  10.   if(color_bits == 1)       { color_bits =  1; }
  11.   else if(color_bits <= 4)  { color_bits =  4; }
  12.   else if(color_bits <= 8)  { color_bits =  8; }
  13.   else if(color_bits <= 16) { color_bits = 16; }
  14.   else if(color_bits <= 24) { color_bits = 24; }
  15.   else                      { color_bits = 32; }
  16.  
  17.   return color_bits;
  18. }
  19.  
  20. #include "record.h"
  21.  
  22. static PBITMAPINFO CreateBitmapInfoStruct(HBITMAP hBmp)
  23. {
  24.   BITMAP      bmp;
  25.   PBITMAPINFO pbmi;
  26.   WORD        cClrBits;
  27.  
  28.   // Retrieve the bitmap's color format, width, and height.
  29.  
  30.   if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp)) {
  31.     // error!
  32.   }
  33.  
  34. #if 0
  35.   REC << "LONG   bmType:       " << bmp.bmType       << "\n";
  36.   REC << "LONG   bmWidth:      " << bmp.bmWidth      << "\n";
  37.   REC << "LONG   bmHeight:     " << bmp.bmHeight     << "\n";
  38.   REC << "LONG   bmWidthBytes: " << bmp.bmWidthBytes << "\n";
  39.   REC << "WORD   bmPlanes:     " << bmp.bmPlanes     << "\n";
  40.   REC << "WORD   bmBitsPixel:  " << bmp.bmBitsPixel  << "\n";
  41.   REC << "LPVOID bmBits:       " << (int)bmp.bmBits  << "\n";
  42. #endif
  43.  
  44.   // Convert the color format to a count of bits.
  45.  
  46.   cClrBits = get_color_bits(bmp);
  47.  
  48.   // Allocate memory for the BITMAPINFO structure. (This structure
  49.   // contains a BITMAPINFOHEADER structure and an array of RGBQUAD data
  50.   // structures.)
  51.  
  52.   if (cClrBits != 24) {
  53.     size_t size = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 ^ cClrBits);
  54.     pbmi = (PBITMAPINFO)malloc(size);
  55.     memset(pbmi, size, 0); // Currently, this has no meaning.
  56.   } else {
  57.     // There is no RGBQUAD array for the 24-bit-per-pixel format.
  58.     size_t size = sizeof(BITMAPINFOHEADER);
  59.     pbmi = (PBITMAPINFO)malloc(size);
  60.     memset(pbmi, size, 0); // Currently, this has no meaning.
  61.   }
  62.  
  63.   /* Initialize the fields in the BITMAPINFO structure. */
  64.  
  65.   pbmi->bmiHeader.biSize     = sizeof(BITMAPINFOHEADER);
  66.   pbmi->bmiHeader.biWidth    = bmp.bmWidth;
  67.   pbmi->bmiHeader.biHeight   = bmp.bmHeight;
  68.   pbmi->bmiHeader.biPlanes   = bmp.bmPlanes;
  69.   pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel;
  70.  
  71.   // If the bitmap is not compressed, set the BI_RGB flag.
  72.   pbmi->bmiHeader.biCompression = BI_RGB; // If the bitmap is compressed.
  73.  
  74.   // Compute the number of bytes in the array of color
  75.   // indices and store the result in biSizeImage.
  76.   pbmi->bmiHeader.biSizeImage = (pbmi->bmiHeader.biWidth + 31) / 32 * 4
  77.                                 * pbmi->bmiHeader.biHeight
  78.                                 * cClrBits;
  79.  
  80.   pbmi->bmiHeader.biXPelsPerMeter = 0;
  81.   pbmi->bmiHeader.biYPelsPerMeter = 0;
  82.  
  83.   if(cClrBits < 24) {
  84.     pbmi->bmiHeader.biClrUsed = 1 << cClrBits;
  85.   } else {
  86.     pbmi->bmiHeader.biClrUsed = 0;
  87.   }
  88.  
  89. #if 0
  90.   REC << "pbmi->bmiHeader.biClrUsed: " << pbmi->bmiHeader.biClrUsed << "\n";
  91. #endif
  92.  
  93.   // Set biClrImportant to 0, indicating that all of the
  94.   // device colors are important.
  95.   pbmi->bmiHeader.biClrImportant = 0;
  96.  
  97.   return pbmi;
  98. }
  99.  
  100. // The following example code defines a function that
  101. // initializes the remaining structures, retrieves the array
  102. // of palette indices, opens the file, copies the data, and
  103. // closes the file.
  104.  
  105. static void make_bitmapfileheader(PBITMAPFILEHEADER hdr, const PBITMAPINFOHEADER pbih)
  106. {
  107.   hdr->bfType = 0x4d42;        /* 0x42 = "B" 0x4d = "M" */
  108.  
  109.   // Compute the size of the entire file.
  110.  
  111.   hdr->bfSize = (DWORD)(sizeof(BITMAPFILEHEADER)
  112.                              + pbih->biSize
  113.                              + pbih->biClrUsed * sizeof(RGBQUAD)
  114.                              + pbih->biSizeImage);
  115.  
  116.   hdr->bfReserved1 = 0;
  117.   hdr->bfReserved2 = 0;
  118.  
  119.   // Compute the offset to the array of color indices.
  120.  
  121.   hdr->bfOffBits = (DWORD)(sizeof(BITMAPFILEHEADER)
  122.                            + pbih->biSize
  123.                            + pbih->biClrUsed * sizeof(RGBQUAD));
  124. }
  125.  
  126. #define MAXWRITE 16384
  127.  
  128. void CreateBMPFile(FILE_NEW& fp, PBITMAPINFO pbi, HBITMAP hBMP, HDC hDC)
  129. {
  130.   BITMAPFILEHEADER hdr;       // bitmap file-header
  131.   PBITMAPINFOHEADER pbih;     // bitmap info-header
  132.   LPBYTE lpBits;              // memory pointer
  133.   DWORD cb;                   // incremental count of bytes
  134.   BYTE* hp;                   // byte pointer
  135.  
  136.   pbih = (PBITMAPINFOHEADER) pbi;
  137.   lpBits = (LPBYTE)malloc(pbih->biSizeImage * 2);
  138.  
  139.   if(!lpBits) {
  140.     // error!
  141.   }
  142.  
  143.   // Retrieve the color table (RGBQUAD array) and the bits
  144.   // (array of palette indices) from the DIB.
  145.  
  146. #if 0
  147.   REC << "pih->biClrUsed: " << pbih->biClrUsed << "\n";
  148. #endif
  149.  
  150.   if(!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight,
  151.       lpBits, pbi, DIB_RGB_COLORS)) {
  152.           // error!
  153.   }
  154.  
  155. #if 0
  156.   REC << "pih->biClrUsed: " << pbih->biClrUsed << "\n";
  157. #endif
  158.  
  159. #if 1
  160.   pbih->biClrUsed = 2;
  161. #endif
  162.  
  163.   make_bitmapfileheader(&hdr, pbih);
  164.  
  165.   // Copy the BITMAPFILEHEADER into the .BMP file.
  166.  
  167.   fp.write((LPVOID)&hdr, sizeof(BITMAPFILEHEADER), 1);
  168.  
  169.   // Copy the BITMAPINFOHEADER and RGBQUAD array into the file.
  170.  
  171. #if 0
  172.   REC << "pih->biClrUsed: " << pbih->biClrUsed << "\n";
  173. #endif
  174.  
  175. #if 1
  176.   RGBQUAD white = {  0,   0,   0};
  177.   RGBQUAD black = {255, 255, 255};
  178.   pbi->bmiColors[0] = white;
  179.   pbi->bmiColors[1] = black;
  180. #endif
  181.  
  182.   fp.write((LPVOID)pbih,
  183.     sizeof(BITMAPINFOHEADER) + pbih->biClrUsed * sizeof(RGBQUAD), 1);
  184.  
  185.   // Copy the array of color indices into the .BMP file.
  186.  
  187.   // dwTotal = cb = pbih->biSizeImage;
  188.   cb = pbih->biSizeImage;
  189.   hp = lpBits;
  190.   while(cb > MAXWRITE)  {
  191.     fp.write((LPSTR)hp, (size_t)MAXWRITE, 1);
  192.     cb -= MAXWRITE;
  193.     hp += MAXWRITE;
  194.   }
  195.   fp.write((LPSTR)hp, (int)cb, 1);
  196.  
  197.   // Free memory.
  198.  
  199.   free(lpBits);
  200. }
  201.  
  202. void OutputBMPFile(FILE_NEW& fp, HBITMAP hBMP, HDC hDC)
  203. {
  204.   PBITMAPINFO pbmi;
  205.   pbmi = CreateBitmapInfoStruct(hBMP);
  206.   CreateBMPFile(fp, pbmi, hBMP, hDC);
  207.   free(pbmi);
  208. }
  209.